package com.haizhi.crm.biz.service.impl;


import com.haizhi.crm.biz.dao.BrowseCountDao;
import com.haizhi.crm.biz.model.BrowseCountDo;
import com.haizhi.crm.biz.service.BrowseCountService;
import com.haizhi.crm.common.constant.BizStatus;
import com.haizhi.crm.common.constant.CrmSchema;
import com.haizhi.crm.common.exception.UnexpectedStatusException;
import com.haizhi.crm.common.model.Response;
import com.haizhi.crm.persist.builder.PersistFactory;
import com.haizhi.crm.persist.builder.PersistReqBuilder;
import com.haizhi.crm.persist.builder.SourceBuilder;
import com.haizhi.crm.persist.constant.PersistTarget;
import com.haizhi.crm.persist.service.PersistService;
import com.haizhi.crm.search.builder.SearchQoBuilder;
import com.haizhi.crm.search.service.SearchService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 浏览统计service
 * Created by yangyijun on 2018/06/13
 */
@Service
public class BrowseCountServiceImpl implements BrowseCountService {

    @Autowired
    private BrowseCountDao browseCountDao;
    @Autowired
    private SearchService searchService;
    @Autowired
    private PersistService persistService;

    /**
     * 浏览统计
     *
     * @param entityType
     * @param entityKey
     */
    @Transactional(readOnly = false)
    public void count(String entityType, String entityKey) {

        BrowseCountDo browseCount = this.browseCountDao.queryByCondition(entityType, entityKey);

        int counts = 1;
        if (browseCount == null) {
            this.browseCountDao.insertBrowseCount(entityType, entityKey, 1);
        } else {
            counts = browseCount.getCounts() + 1;
            this.browseCountDao.updateCounts(counts, browseCount.getId());
        }

        PersistReqBuilder rb = PersistFactory.persistReqBuilder(CrmSchema.CRM, entityType);
        rb.addTargets(PersistTarget.ES);
        // SourceBuilder
        SourceBuilder sb = PersistFactory.sourceBuilder(entityKey);
        sb.updateNormalField("browse_count", counts);
        rb.addSource(sb);

        persistService.bulkPersist(rb.get());
    }


    /**
     * 查询浏览量
     *
     * @param entityType
     * @param entityKey
     * @return
     */
    public int queryBrowseCount(String entityType, String entityKey) {
        BrowseCountDo browseCount = this.browseCountDao.queryByCondition(entityType, entityKey);
        if (browseCount != null)
            return browseCount.getCounts();
        else
            return 0;
    }

    @Override
    public Response hotSearchWords(String entityType, Integer limit) {
        try {
            List<BrowseCountDo> browseCountDos = new ArrayList<>();
            SearchQoBuilder searchQoBuilder = getBrowsesAndBuilder(entityType, limit, browseCountDos);
            if (CollectionUtils.isEmpty(browseCountDos)) {
                return Response.success(browseCountDos);
            }
            List<BrowseCountDo> subList = new ArrayList<>();
            if (browseCountDos.size() > limit) {
                subList.addAll(browseCountDos.subList(0, limit));
            } else {
                subList.addAll(browseCountDos);
            }

            List<String> objectKeys = new ArrayList<>();
            for (BrowseCountDo browseCountDo : subList) {
                objectKeys.add(browseCountDo.getEntityKey());
            }
            searchQoBuilder.addTermFilter("object_key", objectKeys.toArray());
            searchQoBuilder.addSort("browse_count", "desc" );
            Object data = searchService.search(searchQoBuilder.get()).getSearchResp().getData();
            return Response.success(data);
        } catch (Exception e) {
            throw new UnexpectedStatusException(BizStatus.BROWSE_COUNT_ERROR, e);
        }
    }

    private SearchQoBuilder getBrowsesAndBuilder(String entityType, Integer limit, List<BrowseCountDo> browseCountDos) {
        SearchQoBuilder searchQoBuilder = new SearchQoBuilder();
        searchQoBuilder.setGraph(CrmSchema.CRM);
        searchQoBuilder.setPageNo(1);
        searchQoBuilder.setPageSize(limit);
        if (StringUtils.isBlank(entityType)) {
            Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "counts" ));
            browseCountDos.addAll(browseCountDao.findAll(sort));
            searchQoBuilder.addSchemas(CrmSchema.COMPANY);
            searchQoBuilder.addSchemas(CrmSchema.EVENT_INNER);
            searchQoBuilder.addSchemas(CrmSchema.EVENT_OUTTER);
            searchQoBuilder.addSchemas(CrmSchema.PRODUCT);
            searchQoBuilder.addSchemas(CrmSchema.VISIT_RECORD);
        } else {
            browseCountDos.addAll(browseCountDao.findByEntityType(entityType));
            searchQoBuilder.addSchemas(entityType);
        }
        return searchQoBuilder;
    }
}
